package pers.lonestar.framework.utils.support.read;

import java.util.List;

import pers.lonestar.framework.utils.support.annotations.ExcelSheetProperty;
import pers.lonestar.framework.utils.support.exception.ExcelAnalysisException;
import pers.lonestar.framework.utils.support.metadata.read.ReadSheet;
import reactor.core.publisher.Flux;

public class ExcelReaderSheetBuilder {
    private final ReadSheet readSheet;
    private ExcelReader excelReader;

    public ExcelReaderSheetBuilder() {
        this.readSheet = new ReadSheet();
    }

    public ExcelReaderSheetBuilder(ExcelReader excelReader) {
        this.readSheet = new ReadSheet();
        this.excelReader = excelReader;
    }

    public ExcelReaderSheetBuilder sheetIndex(Integer sheetNumber) {
        this.readSheet.setSheetIndex(sheetNumber);
        return this;
    }

    public ExcelReaderSheetBuilder sheetName(String sheetName) {
        this.readSheet.setSheetName(sheetName);
        return this;
    }

    public ExcelReaderSheetBuilder head(Class<?> headClass) {
        this.readSheet.setHeadClass(headClass);
        return this;
    }

    public ExcelReaderSheetBuilder head(Class<?> headClass, Integer headNum) {
        this.readSheet.setHeadClass(headClass);
        this.readSheet.setHeadNum(headNum);
        return this;
    }

    public ExcelReaderSheetBuilder head(List<String> headNameList) {
        this.readSheet.setHeadNameList(headNameList);
        return this;
    }

    public ExcelReaderSheetBuilder head(List<String> headNameList, Integer headNum) {
        this.readSheet.setHeadNameList(headNameList);
        this.readSheet.setHeadNum(headNum);
        return this;
    }

    public ReadSheet build() {
        Class<?> headClass = this.readSheet.getHeadClass();
        if (headClass != null) {
            ExcelSheetProperty sheetProperty = headClass.getAnnotation(ExcelSheetProperty.class);
            if (sheetProperty != null) {
                if (this.readSheet.getSheetIndex() == null) {
                    this.readSheet.setSheetIndex(sheetProperty.index());
                }
                if (this.readSheet.getSheetName() == null) {
                    this.readSheet.setSheetName(sheetProperty.name());
                }
            }
        }
        return readSheet;
    }

    public Flux<?> doRead() {
        if (excelReader == null) {
            throw new ExcelAnalysisException("Must use 'EasyExcelFactory.read().sheet()' to call this method");
        }
        return excelReader.read(build()).doFinally(signalType -> excelReader.finish());
    }
}
